#!/usr/bin/env python
# coding: utf-8

# In[11]:


import wave
import numpy as np
import pylab as plt
from IPython import get_ipython
from scipy.signal import firwin
from scipy.signal import get_window
from utils import *

get_ipython().run_line_magic('matplotlib', 'inline')
np.set_printoptions(precision=4)

# In[12]:


PHASE = 8
TAPS = 32
taps = firwin(TAPS * PHASE, 1 / PHASE, window="blackman")
# scaling
taps = taps * PHASE

c = []
for i in range(PHASE):
    c += get_c(TAPS, i / PHASE).tolist()

taps = np.array(c)

# In[13]:


out_sample = 0
sample_inc = 1.001

# In[14]:


fname = "input.wav"
f = wave.open(fname, 'rb')

f_out = wave.open("wave_out.wav", "wb")
f_out.setframerate(48000)
f_out.setsampwidth(3)
f_out.setnchannels(1)

# In[15]:


audio_delay_line = np.zeros(TAPS)
delay_line_sample = -TAPS


# In[16]:


def sample_to_int(data):
    d = int.from_bytes(data, byteorder='little', signed=True)
    return d


def int_to_sample(data):
    d = int(data)
    d = max(-8388608, min(d, 8388607))
    return d.to_bytes(3, byteorder='little', signed=True)


# In[17]:


# bank selection
def c(p):
    i_p = p
    i = [x + p * TAPS for x in range(TAPS)]
    return taps[i]


# In[18]:


def calc_fir(data, phase):
    return np.sum(audio_delay_line * np.array(get_c(TAPS, phase, 1.0)))


# In[19]:


def process_sample(data):
    global delay_line_sample
    global out_sample
    global audio_delay_line
    audio_delay_line = np.roll(audio_delay_line, 1)
    audio_delay_line[0] = data
    delay_line_sample += 1
    while out_sample < delay_line_sample:
        rem = out_sample % 1
        ret = calc_fir(data, rem)
        f_out.writeframes(int_to_sample(ret))
        out_sample += sample_inc


# In[ ]:


while True:
    data = f.readframes(1)
    if len(data) == 0:
        break
    process_sample(sample_to_int(data))

# In[ ]:


f.close()
f_out.close()
